# -*- coding: utf-8 -*-

## Version Info:
## ---------------------------------------------------
## 1.50 - Too Much to list..
##

import  string,traceback,os
from    re          import findall as reFindall, compile as reCompile, sub as reSub, DOTALL as reDotAll, search as reSearch
from    urllib      import quote_plus   as Quoteplus, urlencode as Urlencode
from    xbmcgui     import ListItem as xListItem
import  core

class Torrents:
    def __init__(self,win,PathName):
        self.win            =   win
        self._              =   self.win._
        self.Version        =   '1.50'
        self.Dir            =   'TVNzb'
        self.BaseUrl        =   'http://www.tvnzb.com'
        self.Title          =   'TVNzb'
        self.win.Title      =   self.Title
        self.win.SiteLabel  =   self.Title
        self.FileType       =   'nzb'

        ## TimeOut
        self.TIMEOUT        =   int(30.0)
        
        ## Display Info
        self.LABEL_         =   ['Date','New','Hits','Size']

        self.KeyMenus               =   {'350': {'A':('Select/Action','','getaction')               ,   \
                                                 'B':('','','')                                     ,   \
                                                 'X':('Back to Main','','rootmenu')                 ,   \
                                                 'Y':('','','')}                                    ,   \
                                         '38':  {'A':('Select/Action','','rootmenu')                ,   \
                                                 'X':('','','')}                                    ,   \
                                         '0':   {'A':('Select/Action','','')}}

        ## Page Info
        self.InitPage       =   1
        self.Page           =   '/page/%s/'
        self.Page_Made      =   str(self.Page   %   str(self.InitPage))

        ## Check and Add In Details to main Config file if they dont Exist..
        if not self.win.Sites.has_key(self.Title)            : self.win.Sites[self.Title]            = {}
        if not self.win.Sites[self.Title].has_key('LABEL_')  : self.win.Sites[self.Title]['LABEL_']  = self.LABEL_[0]
        if not self.win.Sites[self.Title].has_key('TIMEOUT') : self.win.Sites[self.Title]['TIMEOUT'] = self.TIMEOUT

        ### Pass these Parameters Back for Ease ###
        if not self.win.Modules.has_key('Site')              :   self.win.Modules['Site']    =   {} 
        self.win.Modules['Site'][self.Title]                 =   {}
        self.win.Modules['Site'][self.Title]['Path']         =   PathName
        self.win.Modules['Site'][self.Title]['FileType']     =   self.FileType

        self.UpdateAll()

####################################################################################################################
######## START ###################### COMMUNICATION ################################################################      
####################################################################################################################
        
    ##good
    def UpdateAll(self) :
        try :
            self.win.xPrint('--UpdateAll')
            self.UpdateTimeout(self.TIMEOUT)
        except:
            traceback.print_exc()


    ##good
    def UpdateTimeout(self,timeout) :
        try :
            self.TIMEOUT    =   int(self.win.Sites[self.Title]['TIMEOUT'])
        except:
            traceback.print_exc()
            self.TIMEOUT    =   timeout
        

    ##good
    def GetDownloads(self,Actions,Search):
        try :
            self.win.xPrint('--GetDownloads')

            ## If its the first run then build Flag file and run the config first..
            FLAGFILE    =   str(self.win.Site_) + str(self.Dir) +'\\first.run'
            if not (os.path.isfile(FLAGFILE))    :
                self.win.xPrint('** Config Needs to be run **')
                f = open(FLAGFILE,"wb")
                f.close()
                self.ConfigMenu()
        
            ## ReAssign default Variables that have been passed
            self.Search     =   Search
            Name            =   Actions[0]
            Url             =   Actions[1]
            Action          =   Actions[2]
            
            self.PageKeys   =   {'A':('Select/Action','','getaction'),'B':('','',''),'X':('Back to Main','','rootmenu'),'Y':('','','')}

            print '----------------------------------------------'
            print 'Url: '+ str(Url)
            print '----------------------------------------------'

            ## Now download the Data from the Url requested..
            Result      =   self.win.UrlThread(Url                                                  ,\
                                               timeout=int(self.win.Sites[self.Title]['TIMEOUT']))
            if Result   ==  None    :   raise Exception

            ## Now parse the website data
            if    Action == 'files'       :
                self.CurrPage   =   int(Url.rsplit('/',2)[-2])
                self.PrevNo     =   self.CurrPage - 1
                self.PrevPage   =   reSub('/page/'+ str(self.CurrPage) +'/','/page/'+ str(self.PrevNo) +'/',Url)
                self.NextNo     =   self.CurrPage + 1
                self.NextPage   =   reSub('/page/'+ str(self.CurrPage) +'/','/page/'+ str(self.NextNo) +'/',Url)
                Data    =   self.ListFiles(Result,Search,self.LABEL_)
            else                            :   return None        

            ## Update Keymenus with the PageKeys..
            self.KeyMenus['350'].update(self.PageKeys)
            return Data
        except :
            traceback.print_exc()
            self.win.xPrint('==GetDownloads')
            return None


    ##good
    def ListFiles(self,Data,Search,Extras) :
        try :
            self.win.xPrint('--ListFiles')
            ## Initialise Variables that will be passed back ##
            Tor                     =   {}
            Tor_Array               =   []
            Label2                  =   self.win.Sites[self.Title]['LABEL_']
            self.win.SiteLabel      =   self.Title +' ['+ str(Label2) +']'         

            Exp     =   reCompile('<tr.*?<font title=\'.*?\'>(.*?)</font>.*?'   ## Date
                                  '<td.*?>(.*?)</td>.*?'                        ## Url and Name
                                  '<td.*?>(.*?)</td>.*?'                        ## New
                                  '<td.*?>(.*?)</td>.*?'                        ## Hits
                                  '<td.*?>(.*?)</td>.*?'                        ## Size
                                  '</tr>',reDotAll)
            Tar     =   reFindall(Exp,Data)
            print 'Recs:'+ str(len(Tar))
            print str(Tar[0])
            self.Pages(Data)

            No   =   0
            for _a in Tar  :
                NmUrl   =   reFindall('<a href=\'(.*?)\'.*?>(.*?)</a>',_a[1])
                if len(NmUrl) == 1      :
                    Nm                  =   NmUrl[0][1]
                    Tor[Nm]             =   {}
                    Tor[Nm]['Url']      =   NmUrl[0][0]
                    Tor[Nm]['Size']     =   str(_a[4])
                    Tor[Nm]['Date']     =   str(_a[0])
                    Tor[Nm]['New']      =   str(_a[2])
                    Tor[Nm]['Hits']     =   str(_a[3])
                    Tor[Nm]['Action']   =   'download'
                    Health              =   4
                    No = No + 1
                    Tor[Nm]['Health']   =   str(Health)
                    Health_Img  =   self.win.MEDIA +'health-'+ str(Health) +'.png'

                    ## Now Create Extra Information Tags to be displayed when focused.
                    ExtraInf    =   ''
                    for xtra in Extras  :
                        ExtraInf    +=   str(xtra)+':'+ str(Tor[Nm][str(xtra)])+ ' / '

                    TORITEM     =   xListItem(Nm,Tor[Nm][Label2],ExtraInf,Health_Img)
                    Tor_Array.append(TORITEM)

            self.win.xPrint('++ListFiles')            
            return {'Torrents':Tor,'TorListItem':Tor_Array}         
        except :
            traceback.print_exc()
            self.win.xPrint('==ListFiles')
            return None

 
    ##good
    def Pages(self,Data) :
        try :
            self.win.xPrint('++Pages')
            if ( reSearch('/page/' + str(self.NextNo) + '/',Data) ) :
                ## Setup Page Next Info
                Name    =   'Next Page - (%s)'      %   str(self.NextNo)
                Url     =   str(self.NextPage)
                Action  =   'files'
                self.PageKeys['B']  =   (Name,Url,Action)
            if self.CurrPage > self.InitPage    :
                ## Setup Page Prev Info
                Name        =   '(%s) - Prev Page'  %   str(self.PrevNo)
                Url         =   str(self.PrevPage)
                Action      =   'files'
                self.PageKeys['Y']  =   (Name,Url,Action)
                    
            self.win.xPrint('++Pages')
        except :
            traceback.print_exc()
            self.win.xPrint('==Pages')



####################################################################################################################
######## START ###################### TORRENT/FILE ACTIONS #########################################################      
####################################################################################################################

    ##good
    def KeyAction(self,Buttons,Labels,Search):
        try :
            self.win.xPrint('--KeyAction: '+ str(Labels) + '- '+ str(Buttons))
            Name        =   Buttons[0]
            Url         =   Buttons[1]
            Action      =   Buttons[2]
            
            ## Rootmenu when Initially called..
            if      Action      ==  'rootmenu'  :
                xName           =   ''
                xUrl            =   self.BaseUrl +'/nzbs' + self.Page_Made
                xAction         =   'files'
                return True,True,(xName,xUrl,xAction)

            ## Read action from the Item record..
            elif    Action      ==  'getaction' :
                xName           =   Labels[0]
                xUrl            =   self.win.Torrents[Labels[0]]['Url']
                xAction         =   self.win.Torrents[Labels[0]]['Action']

                ## Group all extra records in here for those actions that will be read from
                ## the actual record itself. ie cat,subcat,files ...

                ## Url is for actual data of a torrent file.
                if      xAction     ==  'download'  :
                    self.win.UpdateProgress(self._[26],0,self._[27])
                    Result          =   self.GetTorrent(Labels[0],                              \
                                                        self.win.Torrents[Labels[0]]['Url'])
                    self.win.UpdateProgress(self._[31],-1)
                    return Result,False,()
                else                                :
                    ## This Option is to get the 'cat/subcat options
                    return True,True,(xName,xUrl,xAction)

            ## Search Functon selected
            elif    ( Search != None )  :
                Search_Txt      =   Quoteplus(Search)
                SearchBase      =   '/search/?q='+ str(Search_Txt) +'&emu_subcat=-1&fpn=p&searchaction=Go&emu_subcat_done=-1'
                xName           =   ''
                xUrl            =   self.BaseUrl + str(SearchBase) +'&'+ str(self.Sort_D) +'&'+ str(self.Page_Made)
                xAction         =   'files'
                return True,True,(xName,xUrl,xAction)

            ## Config Options
            elif    Action      ==  'configmenu'    :
                self.ConfigMenu()
                return True,False,()


            ## Nothing To Do..
            self.win.xPrint('Cant Find anything to do.')
            self.win.xPrint('++KeyAction')
            return True,False,()
        except :
            traceback.print_exc()    
            self.win.UpdateProgress(self._[31],-1)
            self.win.xPrint('==KeyAction')
            return False,False,()


    ##good
    def ConfigMenu(self):
        try :
            self.win.xPrint('--ConfigMenu')
            OK = False
            while not ( OK )    :            
                ## Available Configurations for Controller..
                Config      =   [['Timeout [' + str(self.win.Sites[self.Title]['TIMEOUT'])   +']' ,'TIMEOUT'  ,'INT']   , \
                                 ['**** DONE ****'  ,'OK','OK']]

                ## Display Menu.
                MenuList            =   []
                for List in Config  :
                    MenuList.append(List[0])
                Answer = self.win.Menu.select(self._[14],MenuList)

                ## Now work on the Results.
                if Answer != -1         :
                    Result  =   -1
                    if      Config[Answer][2]   ==  'SUB1'   :
                        if      TMPDEF1 + 1  ==  len(ArrOpt1)   :   Result   =   str(ArrOpt1[0])
                        else                                    :   Result   =   str(ArrOpt1[TMPDEF1 + 1])                

                    elif    Config[Answer][2]   ==  'SUB2'   :
                        if      TMPDEF2 + 1  ==  len(ArrOpt2)   :   Result   =   str(ArrOpt2[0])
                        else                                    :   Result   =   str(ArrOpt2[TMPDEF2 + 1])                

                    elif    Config[Answer][2]   ==  'INT'   :
                        Result  =   self.win.Menu.numeric(0,str(MenuList[Answer]) +': ['+                           \
                                                          str(self.win.Sites[self.Title][Config[Answer][1]]) +']')

                    elif    Config[Answer][2]   ==  'OK'    :
                        OK = True
                        
                    if Result == -1 or Result == '' :
                        self.win.xPrint('-1 or empty return so dont update it..')
                    else                            :
                        self.win.Sites[self.Title][Config[Answer][1]] = str(Result)
                        self.UpdateAll()
                        self.win.ResetVars()
##                        if ( self.UpdateCookies() ) :   self.win.Menu.ok('Cookies..','Cookies Updated')
##                        else                        :   self.win.Menu.ok('Cookies..','Update Failure')
                else                    :
                    OK = True
            self.win.xPrint('++ConfigMenu')
        except:
            traceback.print_exc()
            self.win.xPrint('==ConfigMenu')


####################################################################################################################
######## START ###################### TORRENTS ADDED AND LISTED ####################################################      
####################################################################################################################

    #good
    def GetTorrent(self,Name,Url):
        try :
            self.win.xPrint('--GetTorrent :'+ str(Name))

            ## Check that a Ctrl Module is loaded if not choose one.
            if not self.win.ModFunc.has_key('Ctrl') :
                Ready = (self.win.LoadModule('Ctrl','Controller',xFilter=self.FileType))
            else                                    :
                if self.win.ModFunc['Ctrl'].FileType != self.FileType   :
                    Ready = (self.win.LoadModule('Ctrl','Controller',xFilter=self.FileType))
                else                                                    :
                    Ready = True

            ## If Ctrl Module present continue..
            if ( Ready )                            :                
                ## Now download the Data from the Url requested..
                Result      =   self.win.UrlThread(Url                                                  ,\
                                                   timeout=int(self.win.Sites[self.Title]['TIMEOUT']))
                if Result   ==  None    :   raise Exception
                
                ## Send data to be Saved.. 
                PathnFile =   self.win.SaveFiles(self.FileType,Name,Result)
                if PathnFile    !=  None    :
                    Answer      =   self.win.ModFunc['Ctrl'].SendTorrent(PathnFile[0],PathnFile[1])
                    return  Answer
                else                        :
                    raise Exception
            else                                    :
                self.win.Menu.ok(self._[86],self._[87],self._[88])

            self.win.xPrint('++GetTorrent')
            return False
        except :
            traceback.print_exc()
            self.win.xPrint('==GetTorrent')
            return False

